package com.topscomm.mpm.script;

import cn.hutool.core.collection.CollectionUtil;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.BusinessException;
import com.topscomm.cbo.pojo.CboApprovalNodeInsEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboApprovalNodeInsService;
import com.topscomm.cbo.service.ICboUserService;
import com.topscomm.cbo.service.impl.CboApprovalNodeInsService;
import com.topscomm.cbo.service.impl.CboUserService;
import com.topscomm.mpm.MpmScript;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.pojo.*;
import com.topscomm.mpm.service.*;
import com.topscomm.mpm.service.impl.*;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.ITapService;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.DatacodeCache;
import org.springframework.transaction.annotation.Transactional;

import javax.swing.*;
import java.util.*;
import java.util.stream.Collectors;

public class MpmProjectChangeManagerScript extends MpmScript {
    @Transactional(rollbackFor = Exception.class)
    public void changeManager(ITapService service, TapEntity entity) throws Exception {
        CboApprovalNodeInsEntity nodeins = (CboApprovalNodeInsEntity) entity;
        String sourceid = ConvertUtil.convertToString(nodeins.getSourceid());
        ICboUserService cboUserService = (CboUserService) SpringUtil.getBean("cboUserService");
        IMpmProjectChangeManagerService mpmProjectChangeManagerService = (MpmProjectChangeManagerService) SpringUtil.getBean("mpmProjectChangeManagerService");
        IMpmProjectChangeManagerInfoService mpmProjectChangeManagerInfoService = (MpmProjectChangeManagerInfoService) SpringUtil.getBean("mpmProjectChangeManagerInfoService");
        IMpmProjectService mpmProjectService = (MpmProjectService) SpringUtil.getBean("mpmProjectService");
        MpmProjectChangeManagerEntity mpmProjectChangeManagerEntity = mpmProjectChangeManagerService.queryById(sourceid);
        // 获取项目交接子表信息
        List<MpmProjectChangeManagerInfoEntity> infoEntities = mpmProjectChangeManagerInfoService.queryByWhere(" parentid = " + mpmProjectChangeManagerEntity.getId());
        if (CollectionUtil.isEmpty(infoEntities)) {
            return;
        }
        String oldManagerCode = mpmProjectChangeManagerEntity.getOldprojectmanagercode();
        for (MpmProjectChangeManagerInfoEntity infoEntity : infoEntities) {
            String projectcode = "'" + infoEntity.getProjectcode() + "'";
            // 修改项目表项目经理姓名、工号字段
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendSingle(" enabled = 1 and projectcode in ({0}) ", projectcode);
            List<MpmProjectEntity> mpmProjectEntities = mpmProjectService.queryByWhere(sql.toString());
            if (CollectionUtil.isEmpty(mpmProjectEntities)) {
                return;
            }
            changeMpmProject(projectcode,infoEntity,mpmProjectEntities);
            // 修改项目任命表项目经理姓名、工号字段
            changeMpmAppointment(projectcode,infoEntity);
            // 修改项目任命详情表项目经理姓名、工号字段
            changeMpmTeam(projectcode,infoEntity);
            // 修改项目相关方项目经理,将原项目经理的enabled置为0，创建新的项目经理
            changeMpmStakeholder(projectcode,mpmProjectEntities);
            // 获取原项目经理id
            sql.clear();
            sql.appendSingle(" code = '{0}' ",mpmProjectChangeManagerEntity.getOldprojectmanagercode());
            List<CboUserEntity> oldCboUserEntities = cboUserService.queryByWhere(sql.toString());
            long olduserid;
            if(oldCboUserEntities.size() > 0) {
                olduserid = oldCboUserEntities.get(0).getId();
            } else {
                throw new BusinessException("获取原项目经理失败，请联系管理员");
            }
            // 获取现项目经理id
            sql.clear();
            sql.appendSingle(" code = '{0}' ",infoEntity.getNewusercode());
            List<CboUserEntity> newCboUserEntities = cboUserService.queryByWhere(sql.toString());
            long newuserid;
            if(newCboUserEntities.size() > 0) {
                newuserid = newCboUserEntities.get(0).getId();
            } else {
                throw new BusinessException("获取变更项目经理失败，请联系管理员");
            }
            // 修改该项目由项目经理审批的节点办理人
            changeNodePerson(olduserid,newuserid,projectcode);
            // 修改里程碑及任务责任人信息
            changeMilepost(projectcode,infoEntity, oldManagerCode);
            // 修改任务责任人信息
            changeTask(projectcode,infoEntity, oldManagerCode);
            // 修改项目风险、问题、需求项目经理工号和姓名
            changeManagercode(projectcode,infoEntity);
        }
    }
    // 修改项目表项目经理姓名、工号字段
    private void changeMpmProject(String projectcode,MpmProjectChangeManagerInfoEntity infoEntity,List<MpmProjectEntity> mpmProjectEntities) {
        IMpmProjectService mpmProjectService = (MpmProjectService)SpringUtil.getBean("mpmProjectService");
        StringBufferProxy sql = new StringBufferProxy();
        List<BasicEntity> basicEntities = new ArrayList<>();
        for(MpmProjectEntity mpmProjectEntity : mpmProjectEntities) {
            mpmProjectEntity.setProjectmanager(infoEntity.getNewusername());
            mpmProjectEntity.setProjectmanagercode(infoEntity.getNewusercode());
            mpmProjectEntity.setUsername(infoEntity.getNewusername());
            mpmProjectEntity.setUsercode(infoEntity.getNewusercode());
            basicEntities.add(mpmProjectEntity);
        }
        mpmProjectService.updateBatch(basicEntities);
    }
    // 修改项目任命表项目经理姓名、工号字段
    private void changeMpmAppointment(String projectcode,MpmProjectChangeManagerInfoEntity infoEntity) {
        IMpmProjectAppointmentService mpmProjectAppointmentService = (MpmProjectAppointmentService) SpringUtil.getBean("mpmProjectAppointmentService");
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" update {0} set projectmanager = '{1}', " +
                        "projectmanagercode = '{2}' where projectcode in ({3}) ",
                MpmProjectAppointmentEntity.tableName,
                infoEntity.getNewusername(), infoEntity.getNewusercode(),
                projectcode);
        mpmProjectAppointmentService.selectExecute(sql.toString());
    }
    // 修改项目任命详情表项目经理姓名、工号字段
    private void changeMpmTeam(String projectcode,MpmProjectChangeManagerInfoEntity infoEntity) {
        IMpmProjectTeamService mpmProjectTeamService = (MpmProjectTeamService) SpringUtil.getBean("mpmProjectTeamService");
        StringBufferProxy sql = new StringBufferProxy();
        sql.clear();
        sql.appendSingle(" update {0} set username = '{1}', " +
                        "usercode = '{2}' where projectcode in ({3}) and projectrole = '{4}' ",
                MpmProjectTeamEntity.tableName,
                infoEntity.getNewusername(), infoEntity.getNewusercode(),
                projectcode,MpmSystemConst.WorkGroupRoleCode.pm);
        mpmProjectTeamService.selectExecute(sql.toString());
    }
    // 修改项目相关方项目经理,将原项目经理的enabled置为0，创建新的项目经理
    private void changeMpmStakeholder(String projectcode,List<MpmProjectEntity> mpmProjectEntities) {
        MpmProjectStakeholderService mpmProjectStakeholderService = (MpmProjectStakeholderService)SpringUtil.getBean("mpmProjectStakeholderService");
        // 移除旧项目经理
        StringBufferProxy sql = new StringBufferProxy();
        sql.clear();
        sql.appendSingle(" enabled = 1 and projectcode in ({0}) and grouprolecode = '{1}' ",
                projectcode, MpmSystemConst.WorkGroupRoleCode.pm);
        List<MpmProjectStakeholderEntity> mpmProjectStakeholderEntities = mpmProjectStakeholderService.queryByWhere(sql.toString());
        List<BasicEntity> basicEntities = new ArrayList<>();
        for(MpmProjectStakeholderEntity mpmProjectStakeholderEntity : mpmProjectStakeholderEntities) {
            mpmProjectStakeholderEntity.setEnabled(0);
            basicEntities.add(mpmProjectStakeholderEntity);
        }
        mpmProjectStakeholderService.updateBatch(basicEntities);
        // 添加新项目经理
        for(MpmProjectEntity mpmProjectEntity : mpmProjectEntities) {
            mpmProjectStakeholderService.addLeaderGroupMember(mpmProjectEntity, MpmSystemConst.WorkGroupRoleCode.pm);
        }
    }
    // 修改该项目由项目经理审批的节点办理人
    private void changeNodePerson(long olduserid,long newuserid,String projectcode) {
        ICboApprovalNodeInsService cboApprovalNodeInsService = (CboApprovalNodeInsService) SpringUtil.getBean("cboApprovalNodeInsService");
        IMpmProjectChangeManagerService mpmProjectChangeManagerService = (MpmProjectChangeManagerService) SpringUtil.getBean("mpmProjectChangeManagerService");
        StringBufferProxy sql = new StringBufferProxy();
        String[] splitSourcetype = MpmSystemConst.mpmSourcetype.split(",");
        for(String sourcetype : splitSourcetype) {
            sql.clear();
            // 查找数据表中属于项目的所有审批流程,注意立项变更的项目编号字段为projectcode2
            if("MpmProjectChange".equals(sourcetype)) {
                sql.appendSingle(" enabled = 1 and projectcode2 in ({0}) ", projectcode);
            } else {
                sql.appendSingle(" enabled = 1 and projectcode in ({0}) ", projectcode);
            }
            List<Map<String,Object>> res = mpmProjectChangeManagerService.selectExecute("select * from " + sourcetype + " where " + sql.toString());
            String id = res.stream().map(item -> ConvertUtil.convertToString(item.get("id"))).collect(Collectors.joining(","));
            if(!StringUtil.isEmpty(id)) {
                // 查找审批流程下所有需要原项目经理审批的节点，将办理人改为新项目经理
                sql.clear();
                sql.appendSingle(" sourceid in ({0}) and sourcetype = '{1}' and state = '1' and approvaluserid = '{2}' ",id,sourcetype,olduserid);
                List<CboApprovalNodeInsEntity> cboApprovalNodeInsEntities = cboApprovalNodeInsService.queryByWhere(sql.toString());
                List<BasicEntity> basicEntities = new ArrayList<>();
                cboApprovalNodeInsEntities.forEach(cboApprovalNodeInsEntity -> {
                    cboApprovalNodeInsEntity.setApprovaluserid(newuserid);
                    basicEntities.add(cboApprovalNodeInsEntity);
                });
                cboApprovalNodeInsService.updateBatch(basicEntities);
            }
        }
    }
    // 修改里程碑及任务责任人信息
    private void changeMilepost(String projectcode,MpmProjectChangeManagerInfoEntity infoEntity, String oldManagerCode) {
        IMpmProjectMilepostService mpmProjectMilepostService = (MpmProjectMilepostService) SpringUtil.getBean("mpmProjectMilepostService");
        CboUserService cboUserService = (CboUserService) SpringUtil.getBean("cboUserService");
        CboApprovalNodeInsService cboApprovalNodeInsService = (CboApprovalNodeInsService) SpringUtil.getBean("cboApprovalNodeInsService");
        // 修改里程碑及任务责任人
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle("projectcode in ({0}) and enabled = 1 and responsiblecode = '{1}' ",
                projectcode,oldManagerCode);
        // 获取项目中由离职人员负责的里程碑及任务
        List<MpmProjectMilepostEntity> mpmProjectMilepostEntityList = mpmProjectMilepostService.queryByWhere(sql.toString());
        List<BasicEntity> basicEntities = new ArrayList<>();
        for(MpmProjectMilepostEntity mpmProjectMilepostEntity : mpmProjectMilepostEntityList) {
            mpmProjectMilepostEntity.setResponsiblecode(infoEntity.getNewusercode());
            mpmProjectMilepostEntity.setResponsible(infoEntity.getNewusername());
            basicEntities.add(mpmProjectMilepostEntity);
        }
        // 将里程碑及任务的责任人改为交接人
        mpmProjectMilepostService.updateBatch(basicEntities);
        // 不存在里程碑及任务责任人发生变化的情况
        if(mpmProjectMilepostEntityList.size() == 0) {
            return;
        }
        // 存在里程碑及任务责任人发生变化的情况
        List<BasicEntity> updateEntity = new ArrayList<>();
        sql.clear();
        // 查询里程碑及任务下处于里程碑及任务责任人审批阶段的任务反馈和任务关闭流程
        String milepostId = mpmProjectMilepostEntityList.stream().map(item -> ConvertUtil.convertToString(item.getId()))
                .collect(Collectors.joining("','","'","'"));
        // 任务反馈流程
        sql.appendSingle("MPMPROJECTMILEPOST.ID IN ({0}) and MPMPROJECTTASKFEEDBACK.STATE = 1 ",milepostId);
        List<Map<String,Object>> taskFeedbackApprovalList = mpmProjectMilepostService.queryMapByWhere(sql.toString(),"queryTaskFeedback");
        if(taskFeedbackApprovalList.size()>0) {
            for (Map<String, Object> taskFeedbackApprovalMap : taskFeedbackApprovalList) {
                // 查询人员code对应的id
                sql.clear();
                sql.appendSingle(" code = '{0}' ", ConvertUtil.convertToString(taskFeedbackApprovalMap.get("responsiblecode")));
                CboUserEntity cboUserEntity = cboUserService.queryObjectByWhere(sql.toString());
                // 查询里程碑及任务责任人正在审批的流程
                sql.clear();
                sql.appendSingle("SELECT CBOAPPROVALNODEINS.* FROM CBOAPPROVALNODEINS INNER JOIN CBOAPPROVALNODE " +
                                "ON CBOAPPROVALNODEINS.NODEID = CBOAPPROVALNODE.ID WHERE CBOAPPROVALNODEINS.SOURCEID = '{0}' " +
                                "AND  CBOAPPROVALNODEINS.SOURCETYPE = '{1}' AND STATE = 1 AND " +
                                "CBOAPPROVALNODE.APPROVALPARAM LIKE '%milepostcheckfeedback%'",taskFeedbackApprovalMap.get("sourceid"),
                        MpmProjectTaskFeedbackEntity.tableName);
                List<Map<String,Object>> feedbackList = cboApprovalNodeInsService.selectExecute(sql.toString());
                // 存在任务反馈流程正处于里程碑及任务责任人审批节点的流程，将里程碑及任务责任人进行更换
                if(feedbackList.size() > 0) {
                    CboApprovalNodeInsEntity cboApprovalNodeInsEntity = new CboApprovalNodeInsEntity();
                    cboApprovalNodeInsEntity.convertFromMap(feedbackList.get(0));
                    cboApprovalNodeInsEntity.setApprovaluserid(cboUserEntity.getId());
                    updateEntity.add(cboApprovalNodeInsEntity);
                }
            }
        }
        // 任务关闭流程
        sql.clear();
        sql.appendSingle("MPMPROJECTMILEPOST.ID IN ({0}) and MPMPROJECTTASKCLOSE.STATE = 1 ",milepostId);
        List<Map<String,Object>> taskCloseApprovalList = mpmProjectMilepostService.queryMapByWhere(sql.toString(),"queryTaskClose");
        if(taskCloseApprovalList.size() > 0) {
            for (Map<String, Object> taskCloseApprovalMap : taskCloseApprovalList) {
                // 查询人员code对应的id
                sql.clear();
                sql.appendSingle(" code = '{0}' ", ConvertUtil.convertToString(taskCloseApprovalMap.get("responsiblecode")));
                CboUserEntity cboUserEntity = cboUserService.queryObjectByWhere(sql.toString());
                // 查询里程碑及任务责任人正在审批的流程
                sql.clear();
                sql.appendSingle("SELECT CBOAPPROVALNODEINS.* FROM CBOAPPROVALNODEINS INNER JOIN CBOAPPROVALNODE " +
                                "ON CBOAPPROVALNODEINS.NODEID = CBOAPPROVALNODE.ID WHERE CBOAPPROVALNODEINS.SOURCEID = '{0}' " +
                                "AND  CBOAPPROVALNODEINS.SOURCETYPE = '{1}' AND STATE = 1 AND " +
                                "CBOAPPROVALNODE.APPROVALPARAM LIKE '%milepostcheckclose%'",taskCloseApprovalMap.get("sourceid"),
                        MpmProjectTaskCloseEntity.tableName);
                List<Map<String,Object>> closeList = cboApprovalNodeInsService.selectExecute(sql.toString());
                // 存在任务关闭流程正处于里程碑及任务责任人审批节点的流程，将里程碑及任务责任人进行更换
                if(closeList.size() > 0) {
                    CboApprovalNodeInsEntity cboApprovalNodeInsEntity = new CboApprovalNodeInsEntity();
                    cboApprovalNodeInsEntity.convertFromMap(closeList.get(0));
                    cboApprovalNodeInsEntity.setApprovaluserid(cboUserEntity.getId());
                    updateEntity.add(cboApprovalNodeInsEntity);
                }
            }
        }
        // 更新任务反馈和任务关闭的里程碑及任务责任人节点办理人
        cboApprovalNodeInsService.updateBatch(updateEntity);
    }
    // 修改任务责任人信息
    private void changeTask(String projectcode,MpmProjectChangeManagerInfoEntity infoEntity, String oldManagerCode) {
        IMpmProjectTaskService mpmProjectTaskService = (MpmProjectTaskService) SpringUtil.getBean("mpmProjectTaskService");
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle("projectcode in ({0}) and enabled = 1 and responsiblecode = '{1}'",
                projectcode,oldManagerCode);
        List<MpmProjectTaskEntity> mpmProjectTaskEntityList = mpmProjectTaskService.queryByWhere(sql.toString());
        List<BasicEntity> basicEntities = new ArrayList<>();
        for(MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntityList) {
            mpmProjectTaskEntity.setResponsiblecode(infoEntity.getNewusercode());
            mpmProjectTaskEntity.setResponsible(infoEntity.getNewusername());
            basicEntities.add(mpmProjectTaskEntity);
        }
        mpmProjectTaskService.updateBatch(basicEntities);
    }
    // 修改项目风险、问题、需求项目经理工号和姓名
    private void changeManagercode(String projectcode,MpmProjectChangeManagerInfoEntity infoEntity) {
        IMpmProjectProblemService mpmProjectProblemService = (MpmProjectProblemService) SpringUtil.getBean("mpmProjectProblemService");
        IMpmProjectRiskService mpmProjectRiskService = (MpmProjectRiskService) SpringUtil.getBean("mpmProjectRiskService");
        IMpmProjectDemandService mpmProjectDemandService = (MpmProjectDemandService) SpringUtil.getBean("mpmProjectDemandService");
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle("enabled = 1 and projectcode in ({0})",projectcode);
        List<MpmProjectProblemEntity> mpmProjectProblemEntityList = mpmProjectProblemService.queryByWhere(sql.toString());
        List<MpmProjectRiskEntity> mpmProjectRiskEntityList = mpmProjectRiskService.queryByWhere(sql.toString());
        List<MpmProjectDemandEntity> mpmProjectDemandEntityList = mpmProjectDemandService.queryByWhere(sql.toString());
        String managerCode = infoEntity.getNewusercode();
        String managerName = infoEntity.getNewusername();
        // 修改项目问题项目经理工号和姓名
        List<BasicEntity> problemBasicEntityList = new ArrayList<>();
        for(MpmProjectProblemEntity mpmProjectProblemEntity : mpmProjectProblemEntityList) {
            mpmProjectProblemEntity.setProjectmanagercode(managerCode);
            mpmProjectProblemEntity.setProjectmanager(managerName);
            problemBasicEntityList.add(mpmProjectProblemEntity);
        }
        mpmProjectProblemService.updateBatch(problemBasicEntityList);
        // 修改项目风险项目经理工号和姓名
        List<BasicEntity> riskBasicEntityList = new ArrayList<>();
        for(MpmProjectRiskEntity mpmProjectRiskEntity : mpmProjectRiskEntityList) {
            mpmProjectRiskEntity.setProjectmanagercode(managerCode);
            mpmProjectRiskEntity.setProjectmanager(managerName);
            riskBasicEntityList.add(mpmProjectRiskEntity);
        }
        mpmProjectRiskService.updateBatch(riskBasicEntityList);
        // 修改项目需求项目经理工号和姓名
        List<BasicEntity> demandBasicEntityList = new ArrayList<>();
        for(MpmProjectDemandEntity mpmProjectDemandEntity : mpmProjectDemandEntityList) {
            mpmProjectDemandEntity.setProjectmanagercode(managerCode);
            mpmProjectDemandEntity.setProjectmanager(managerName);
            demandBasicEntityList.add(mpmProjectDemandEntity);
        }
        mpmProjectDemandService.updateBatch(demandBasicEntityList);
    }
}
